<template>
  <div>
    <el-cascader
      ref="cascader"
      v-if="isShow"
      v-model="cascaderValue"
      :options="options"
      :props="props"
      :disabled="disabled"
      :placeholder="placeholder"
      filterable
      clearable
    >
    </el-cascader>
  </div>
</template>

<script>
import { getLazyTree } from "@/api/base/region";
export default {
  props: {
    cascaderValue: Array,
    isShow: {
      type: Boolean,
      default: true,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
  },
  data() {
    return {
      options: [],
      props: {
        label: "title",
        id: "id",
        value: "id",
        multiple: true,
        // checkStrictly: true,
        lazy: true,
        leaf: "leaf",
        disabled: this.isDisabledFn,
        lazyLoad: this.lazyLoad,
      },
    };
  },
  watch: {},
  methods: {
    /**
     * @func 表单区域树形数据懒加载
     * @desc 通过点击表单"编辑"进行禁止的切换
     * @param {Object} node - 节点数据
     * @param {Function} resolve - 数据回显
     * */
    async lazyLoad(node, resolve) {
      // const parentCode = node.level === 0 ? "00" : node.data.id;
      if (node.level == 0) {
        if (this.cascaderValue && this.cascaderValue.length > 0) {
          // 存在回显的id我们才去设置回显
          await this.format(); // 这里就是获取第一次要回显的内容了
        } else {
          let res = await this.getFormatChild(node.level, "00"); // 不存在就默认加载第一集节点
          resolve(res);
        }
      } else {
        // 记录选择的，不然会点击字节点加载时丢失数据
        let cascaderList = this.cascaderValue;
        // 有children属性了就不要再请求了,不然字节点会重复
        if (!node.data.children) {
          // 获取子节点数据
          let res = await this.getFormatChild(node.level, node.data.id); // 不存在就默认加载第一集节点
          resolve(res);
        } else {
          resolve([]);
        }
        // 重新把选择的id放回来-
        this.$nextTick(() => {
          this.cascaderValue = [
            ...new Set([...this.cascaderValue, ...cascaderList]),
          ]; //差别： 合并并且去重
        });
      }
    },
    /**
     * @func 请求层级节点数据
     * @desc 通过懒加载lazy的模式执行
     * @param {Number} level - 层级
     * @param {String} parentCode - 父级编号
     * */
    async getFormatChild(level, parentCode) {
      let list = [];
      let stop_level = 1;
      await getLazyTree(parentCode).then(
        (res) => {
          list = res.data.data;
          (list || []).map((ele) => {
            Object.assign(ele, {
              leaf: level >= stop_level,
            });
          });
        },
        (error) => {
          window.console.log(error);
        }
      );
      return list;
    },
    /**
     * @func 格式化递归回显框内多选数据
     * @desc 根据回显的id获取 第一次的数据， id必须是 一条链， 就是当前节点到此节点的一级节点的整条链 id 都要有
     * */
    async format() {
      let res = await this.getFormatChild(0, "00"); // 拿一级数据
      this.cascaderValue.forEach((item) => {
        // 遍历回显的id 二维数组
        if (item.length > 1) {
          item.forEach(async (sitem, index) => {
            if (index == item.length - 1) {
              return; // 如果是一级节点就不用查找了
            }
            let arr = await this.getFormatChild(1, sitem); // 不是一级，获取子级
            this.options = await this.findItem(res, arr, sitem); //  判断当前拿到的子级数据属于哪个一级数据下的子级，并且加到当前一级的children属性下
          });
        }
      });
    },
    /**
     * @func 递归
     * @desc 查找当前节点是属于哪个一级节点的子级，通过options属性来初始化要回显的列表
     * */
    findItem(res, arr, id) {
      let list = [];
      for (let i = 0; i < res.length; i++) {
        if (res[i].value === id) {
          res[i].children = arr; // 有chidlren 也要判断是不是这个children下的子级
        }
        if (res[i].children) {
          this.findItem(res[i].children, arr, id);
        }
        list.push(res[i]);
      }
      return list;
    },
    /**
     * @func 是否禁止
     * @param {Boolean} isTreeDis - 禁止状态
     * */
    isDisabledFn(isTreeDis) {
      if (isTreeDis) {
        return true;
      } else {
        return false;
      }
    },
  },
};
</script>

<style>
</style>